/* 
 * Funkcijos darbui su puslapiavimu
 */
#ifndef PAGING_H
#define PAGING_H

#define PAGE_ALIGN_UP(addr) (((addr) + 4096 - 1) & -4096)

typedef struct page{
  u32int present    : 1;   /* Ar puslapis yra atmintyje, 0- ne, 1- taip */
  u32int rw         : 1;   /* 0- read-only, 1- read/write */
  u32int user       : 1;   /* 0- kernel mode, 1- user mode */
  u32int accessed   : 1;   /* Ar buvo dirbta su puslapiu nuo paskutinio patikrinimo */
  u32int dirty      : 1;   /* Ar buvo kas nors įrašyta į puslapį po paskutinio patikrinimo */
  u32int unused     : 7;   /* Nenaudojami bitai */
  u32int frame      : 20;  /* Tikrasis adresas atmintyje. Viršutiniai 20 bitų */
} page_t;

typedef struct page_table{
  page_t pages[1024]; /* Kadangi bus dviejų lygių puslapiavimas, tai yra 1024 vienoje lentelėje puslapių */
} page_table_t;

typedef struct page_dir{
  page_table_t *tables[1024]; /* Rodyklių masyvas į puslapių lenteles */
   /* 
    * Masyvas kuris laiko adresus puslapių lentelių fizinėje atmintyje.
    * Bus užkraunama į CR3 registrą.
    */
  u32int tPhysical[1024]; 
  u32int tPhysicalAddr; /* Adresas masyvo kuris laiko savyje fizinius adresus puslapių lentelių */
} page_dir_t;

/* Puslapiavimo inicializacija */
boolean init_paging();
/* Skirta pakrauti tam tikrą puslapių direktoriją į CR3 registrą */
void switch_page_dir(page_dir_t *);
/* 
 * Gauname rodyklę, reikalingam puslapiui, jei make=1, tai reikia sukurti puslapių lentelę,
 * kurioje turėtų tas puslapis būti.
 */
page_t *get_page(u32int , int , page_dir_t *);

#endif /* PAGING_H */